package pay.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import pay.common.*;
import pay.entity.HistoryPayment;
import pay.entity.Payment;
import pay.entity.SysUser;
import pay.entity.ap;
import pay.service.sys.ISysUser;
import pay.utils.*;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Antinomy on 17/8/9.
 */
@Service
public class ChangeCardService {
    protected Logger logger = LoggerFactory
            .getLogger(this.getClass().getName());

    @Value("${fy.mchntCd}")
    private String mchnt_cd;

    @Value("${fy.goldAccount.baseUrl}")
    private String jzhBaseUrl;

    @Value("${fy.goldAccount.pathBaseUrl}")
    private String pathBaseUrl;// 测试环境为/jzh 生产无。

    @Value("${fy.goldAccount.logsBaseUrl}")
    private String logBaseUrl;

    @Autowired
    private IPayment paymentService;

    @Autowired
    private IHistoryPayment historyPaymentService;

    @Autowired
    private IOrderJpa OrderJPAService;

    @Autowired
    private ISysUser sysUserService;

    public void syncChangeCardResult() {
        try {
            logger.info("主动查询换卡结果任务开始");
            HqlFilter hqlFilter = new HqlFilter();
            hqlFilter.addEQFilter("cardStatus", CardStatusCode.FY_CHANGE_CARDING);
            List<Payment> changeCardPaymentList = paymentService.findByFilter(hqlFilter);

            if (changeCardPaymentList.size() > 0) {
                for (Payment payment : changeCardPaymentList) {// 用户更换银行卡查询接口中的
                    // 交易流水 指的是
                    // 更换银行卡接口中的流水号
                    String phone = payment.getUserRegistPhone();
                    String mchnt_txn_ssn = "" + System.currentTimeMillis();
                    String txn_ssn = payment.getMchnt_txn_ssn();
                    syncDateFromFY(payment, mchnt_txn_ssn, phone, txn_ssn);
                }
            }
        } catch (Exception e) {
            logger.info("更新用户换卡定时器执行异常 {}", e);
        }

    }

    public void syncCardToChangeStatus(String resp_code, String mchnt_txn_ssn) {
        try {

            logger.info("SyncCardChangeStatus: resp_code={} ,mchnt_txn_ssn={}", resp_code, mchnt_txn_ssn);

            if (!"0000".equals(resp_code))
                return;

            String paymentIdStr = mchnt_txn_ssn.substring(6);
            Long paymentId = Long.parseLong(paymentIdStr);
            Payment payment = paymentService.findById(paymentId);

            if (payment == null) {
                logger.info("查询不到该绑卡记录，paymentId={},mchnt_txn_ssn={}", paymentId, mchnt_txn_ssn);
                return;
            }

            payment.setCardStatus(CardStatusCode.FY_CHANGE_CARDING);
            payment.setMchnt_txn_ssn(mchnt_txn_ssn);
            paymentService.update(payment);


        } catch (Exception e) {
            logger.error("富友换卡请求回调更改绑卡记录状态异常: {}", e);
        }
    }

    public void syncCardFromOnlyFYBackEndChange(String resp_code, String mchnt_txn_ssn, SysUser user,
                                                String mobile_no,String cust_nm, String certif_id, String capAcntNo) {
        try {

            Long userId=user.getId();
            logger.info("SyncCardChangeStatus: resp_code={} ,mchnt_txn_ssn={},userId={}", resp_code, mchnt_txn_ssn, userId);

            if (!"0000".equals(resp_code))
                return;

            String paymentIdStr = mchnt_txn_ssn.substring(6);
            Long paymentId = Long.parseLong(paymentIdStr);
            Payment oldPayment = paymentService.findById(paymentId);

            if (oldPayment == null) {
                oldPayment = paymentService.getByUserId(userId);
            }

            if (oldPayment == null) {
                logger.info("查询不到该绑卡记录，userId={},mchnt_txn_ssn={}", userId, mchnt_txn_ssn);
                return;
            }

            paymentService.updateOldPayment(oldPayment);

           /*------------------更新原来的绑卡记录结束------------------*/
            Payment newPayment = storeNewPayment(mobile_no, cust_nm, certif_id, capAcntNo, user);

            addHistoryPayment(capAcntNo, user, oldPayment, newPayment);

        } catch (Exception e) {
            logger.error("富友换卡请求回调更改绑卡记录状态异常: {}", e);
        }
    }

    public void updateAppChangeCardResult(String mobile_no, String cust_nm, String certif_id, String capAcntNo, SysUser user, List<Payment> userChangePaymentList) {
        Payment willChangePayment = userChangePaymentList.get(0);
        paymentService.updateExistPayment(willChangePayment);

        /*------------------更新原来的绑卡记录结束------------------*/
        Payment newPayment = storeNewPayment(mobile_no, cust_nm, certif_id, capAcntNo, user);

        addHistoryPayment(capAcntNo, user, willChangePayment, newPayment);
    }

    public Payment storeNewPayment(String mobile_no, String cust_nm, String certif_id, String capAcntNo, SysUser user) {
    /*-------------查看新卡是否数据库中已添加--------------*/
        List<Payment> currentPaymentList = getExistingPayments(capAcntNo);

        Payment newPayment = null;
        if (currentPaymentList.size() > 0) { // 新卡已有记录，则更新新卡
            newPayment = paymentService.updateNewPaymentExist(currentPaymentList, certif_id, cust_nm);

        } else {// 没有新卡记录，则创建新卡
            newPayment = paymentService.addNewCard(cust_nm, certif_id, capAcntNo, mobile_no, user);
        }
        return newPayment;
    }

    public List<Payment> getExistingPayments(String capAcntNo) {
        HqlFilter hqlFilter = new HqlFilter();
        hqlFilter.addEQFilter("paymentNo", capAcntNo);
        hqlFilter.addEQFilter("cardStatus", CardStatusCode.PAYMENT_DISPLAY_SHOW);
        return paymentService.findByFilter(hqlFilter);
    }

    public String disBindCard(String mobile, String cardNum) {

        HqlFilter paymentFilter = new HqlFilter();
        paymentFilter.addEQFilter("userRegistPhone", mobile);
        paymentFilter.addEQFilter("paymentNo", cardNum);
        paymentFilter.addEQFilter("cardStatus", CardStatusCode.PAYMENT_DISPLAY_SHOW);

        List<Payment> existingCards = paymentService.findByFilter(paymentFilter);

        if (existingCards.size() != 1) {
            return "同时多张绑卡或者没有绑卡,无法解绑";
        }

        Long orderInProgressAccount = OrderJPAService.getOrderInProgressAccount(cardNum);

        if (orderInProgressAccount > 0) {
            return "存在在途订单,无法解绑";
        }

        Payment disBindPayment = existingCards.get(0);

        Long disBindPaymentId = paymentService.updateOldPayment(disBindPayment);

        return cardNum + " 解绑完成 !";
    }
    public String syncBindCard(String mobile, String cardNum) {
        SysUser user =  sysUserService.getByPhoneNum(mobile);

        if(user == null){
            return "用户不存在: "+mobile;
        }

        List<Payment> currentPaymentList = getExistingPayments(cardNum);
        if (currentPaymentList.size() > 0) {
            return "银行卡已存在: "+cardNum;
        }

        String response = queryUserInfoFromFY(user);

        String resp_code = XmlUtils.getVal(response, "resp_code");
        if (!resp_code.equals("0000")) {
            return  response;
        }

        String user_st = XmlUtils.getVal(response, "user_st");
        //1正常 2已注销 3申请注销
        if (!user_st.equals("1")) {
            return  "用户状态异常: "+user_st;
        }

        String capAcntNo = XmlUtils.getVal(response, "capAcntNo");
        // 检验绑定卡号是否一致
        if (!cardNum.equals(capAcntNo)) {
            return  "银行卡异常: "+cardNum +" != "+capAcntNo;
        }

        String cust_nm = XmlUtils.getVal(response, "cust_nm");
        String certif_id = XmlUtils.getVal(response, "certif_id");

        Payment newPayment = storeNewPayment(mobile, cust_nm, certif_id, capAcntNo, user);

        try {
            sysUserService.upUserByPayment(user.getId(), null, certif_id, cust_nm, ConstantPayment.HAS_FYACCOUNT);
        } catch (Exception e) {
            logger.error("关联更新用户身份证号和姓名异常", e);
        }

        bindCardHistoryPayment(user, capAcntNo, newPayment);

        return newPayment.getPaymentNo()+" 同步成功";
    }


    private String queryUserInfoFromFY(SysUser user) {
        LocalDate today = LocalDate.now();
        String todayString = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        Map<String, String> map = new HashMap<>();
        map.put("ver", "0.44");
        map.put("mchnt_cd", this.mchnt_cd);
        map.put("mchnt_txn_ssn", "" + System.currentTimeMillis());
        map.put("mchnt_txn_dt", todayString);
        map.put("user_ids", user.getName());
        map = MapSortUtil.sortMapByKey(map);

        String pathUrl = String.format("%s/%s", this.pathBaseUrl, "queryUserInfs.action");
        String response = FYApiUtil.sendPostToFYUtils(map, jzhBaseUrl, pathUrl);

        logger.info("query FY UserInfo result : "+response);
        return response;
    }

    private void bindCardHistoryPayment(SysUser user, String capAcntNo, Payment newPayment) {
        try {
            HistoryPayment historyPayment=new HistoryPayment();
            historyPayment.setCompany(ConstantRoute.COMPANY_HUAKANG);
            historyPayment.setPaymentType(CardStatusCode.PAYMENT_TYPE_ADD);
            historyPayment.setNewBankNo(capAcntNo);
            historyPayment.setNewBankName(newPayment.getBankName());
            historyPayment.setUserId(user.getId());
            historyPayment.setPaymentId(newPayment.getId());
            historyPayment.setStatus(1);
            historyPaymentService.add(historyPayment);
        } catch (Exception e) {
            logger.info("<-------------------------ERROR------------------------>");
            logger.error("富友绑卡添加到解绑卡历史表异常!!",e);
        }
    }

    private void addHistoryPayment(String capAcntNo, SysUser user, Payment willChangePayment, Payment newPayment) {
        try {
            HistoryPayment historyPayment = new HistoryPayment();
            historyPayment.setCompany(ConstantRoute.COMPANY_HUAKANG);
            historyPayment.setPaymentType(CardStatusCode.PAYMENT_TYPE_CHANGE);
            historyPayment.setOldBankNo(willChangePayment.getPaymentNo());
            historyPayment.setOldBankName(willChangePayment.getBankName());
            historyPayment.setNewBankNo(capAcntNo);
            historyPayment.setNewBankName(newPayment.getBankName());
            historyPayment.setUserId(user.getId());
            historyPayment.setPaymentId(newPayment.getId());
            historyPayment.setStatus(1);
            historyPaymentService.add(historyPayment);
            //historyPaymentService.add(ConstantRoute.COMPANY_HUAKANG, CardStatusCode.PAYMENT_TYPE_CHANGE, willChangePayment.getPaymentNo(), capAcntNo, user.getId());
        } catch (Exception e) {
            logger.info("<---------------------------ERROR------------------------------>");
            logger.error("富友换卡添加到解绑卡历史表异常!! {}", e);
        }
    }

    public void writeChangeCardResultToFile(String resp_code, String mchnt_txn_ssn, String desc_code) {
        try {
            Long cts = System.currentTimeMillis();
            String log = DateUtil
                    .transferLongToDate("yyyy-MM-dd HH:mm:ss", cts)
                    + "----用户富友换卡结果回调信息:  resp_code = "
                    + resp_code
                    + ",desc_code = "
                    + desc_code
                    + ",mchnt_txn_ssn = "
                    + mchnt_txn_ssn + "\r\n";

            WriteFileUtils
                    .writeFile("AskChangeCardRecord-", "yyyyMM", logBaseUrl +
                                    "/payServerRecords/ChangeCardRecords/",
                            log, cts);
        } catch (Exception e) {
            logger.error("富友换卡结果回调文件失败！{}", e);
        }
    }

    private void syncDateFromFY(Payment payment, String mchnt_txn_ssn,
                                String login_id, String txn_ssn) {

        String allUrl = login_id + "|" + mchnt_cd + "|" + mchnt_txn_ssn + "|" + txn_ssn;
        logger.info("请求富友更换银行卡查询流水号：" + mchnt_txn_ssn + "loginId:" + login_id + "明文:" + allUrl);

        String openResult = handleOrder(login_id, txn_ssn, mchnt_txn_ssn);

        updateExtraInfoAndStatus(payment, mchnt_txn_ssn, login_id, txn_ssn, openResult);

        paymentService.update(payment);
    }

    private void updateExtraInfoAndStatus(Payment payment, String mchnt_txn_ssn, String login_id, String txn_ssn, String openResult) {
        String extraInfo = "";

        if ("-1111".equals(openResult)) {
            logger.info("富友更换银行卡查询异常！mchnt_txn_ssn={},login_id={},txn_ssn={}",
                    mchnt_txn_ssn, login_id, txn_ssn);
            extraInfo = "[-1111]富友更换银行卡查询httpClient异常！";

            payment.setExtraInfo(extraInfo);
            return;
        }

        BeanAndXMLTurn<ap> ff = new BeanAndXMLTurn<ap>();
        ap fmresultFm = ff.XMLStringToBean(openResult, new ap());
        String responseCode = fmresultFm.getPlain().getResp_code();
        String remark = fmresultFm.getPlain().getRemark();

        if (!"0000".equals(responseCode)) {
            logger.info(
                    "富友更换银行卡查询失败！失败的响应码responseCode={},mchnt_txn_ssn={},login_id={},txn_ssn={}",
                    responseCode, mchnt_txn_ssn, login_id, txn_ssn);
            extraInfo = "[" + responseCode + "]" + remark;

            payment.setExtraInfo(extraInfo);
            return;
        }

        String examine_st = fmresultFm.getPlain().getExamine_st();
        if (("2".equals(examine_st))) {// 0：待审核，1：审核成功，2：审核失败
            logger.info(
                    "富友银行卡更换审核失败的响应码responseCode={},审核失败原因remark={}",
                    responseCode, remark);
            extraInfo = "[" + examine_st + "]" + remark;

            payment.setCardStatus(CardStatusCode.PAYMENT_DISPLAY_SHOW);  //还原卡成正常状态
            payment.setChangeCardResult(ChangeCardResultCode.FAILED);

            //保存换卡失败情况到表t_history_payment
            try {
                HistoryPayment historyPayment = new HistoryPayment();
                historyPayment.setCompany(ConstantRoute.COMPANY_HUAKANG);
                historyPayment.setPaymentType(CardStatusCode.PAYMENT_TYPE_CHANGE);
                historyPayment.setOldBankNo(payment.getPaymentNo());
                historyPayment.setOldBankName(payment.getBankName());
                historyPayment.setNewBankNo(fmresultFm.getPlain().getCard_no());
                historyPayment.setNewBankName(fmresultFm.getPlain().getBank_nm());
                historyPayment.setUserId(payment.getUserId());
                historyPayment.setPaymentId(payment.getId());
                historyPayment.setStatus(0);
                historyPayment.setFailMsg(remark);
                historyPaymentService.add(historyPayment);
            } catch (Exception e) {
                logger.info("<---------------------------ERROR------------------------------>");
                logger.error("富友换卡添加到解绑卡历史表异常!! {}", e);
            }
        }else if(("1".equals(examine_st))){
            try {
                SysUser user =  sysUserService.getByPhoneNum(login_id);
                if(user == null){
                    logger.error("updateExtraInfoAndStatus 用户不存在，login_id={}",login_id);
                    return;
                }

                String response = queryUserInfoFromFY(user);
                String resp_code = XmlUtils.getVal(response, "resp_code");
                if (!resp_code.equals("0000")) {
                    logger.error("updateExtraInfoAndStatus 富友查询用户信息 "+response);
                    return;
                }

                String user_st = XmlUtils.getVal(response, "user_st");
                //1正常 2已注销 3申请注销
                if (!user_st.equals("1")) {
                    logger.error("updateExtraInfoAndStatus 用户状态异常 {}",user_st);
                    return;
                }

                //用户正在使用的卡号
                String capAcntNo = XmlUtils.getVal(response, "capAcntNo");
                //用户姓名
                String cust_nm = XmlUtils.getVal(response, "cust_nm");
                //身份证号
                String certif_id = XmlUtils.getVal(response, "certif_id");

                List<Payment> userChangePaymentList =  new ArrayList<>();
                userChangePaymentList.add(payment);
                this.updateAppChangeCardResult(login_id, cust_nm, certif_id, capAcntNo, user, userChangePaymentList);

                Payment hasChandeCard = paymentService.findById(payment.getId());
                payment.setCardStatus(hasChandeCard.getCardStatus());
                payment.setChangeCardResult(hasChandeCard.getChangeCardResult());
                payment.setMchnt_txn_ssn(hasChandeCard.getMchnt_txn_ssn());
                payment.setSupportCompany(hasChandeCard.getSupportCompany());

                sysUserService.upUserByPayment(user.getId(), null, certif_id, cust_nm, ConstantPayment.HAS_FYACCOUNT);
            }catch (Exception e){
                logger.error("updateExtraInfoAndStatus 富友审核成功，处理旧卡失败");
            }

        }

        payment.setExtraInfo(extraInfo);
        return;
    }

    private String handleOrder(String login_id, String txn_ssn,
                               String mchnt_txn_ssn) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("mchnt_cd", mchnt_cd);
        map.put("mchnt_txn_ssn", mchnt_txn_ssn);
        map.put("login_id", login_id);
        map.put("txn_ssn", txn_ssn);
        map = MapSortUtil.sortMapByKey(map);
        String pathUrl = pathBaseUrl + "/queryChangeCard.action";
        return FYApiUtil.sendPostToFYUtils(map, jzhBaseUrl, pathUrl);
    }


}
